import numpy as np
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import LabelEncoder


def load_iris_data():
    # 从当前目录加载Iris数据集
    with open('iris.data', 'r') as file:
        lines = file.readlines()

    # 提取特征和标签
    data = [line.strip().split(',') for line in lines if line.strip()]
    X = np.array([list(map(float, row[:-1])) for row in data])
    y = np.array([row[-1] for row in data])

    return X, y

def euclidean_distance(x1, x2):
    # 计算两个样本之间的欧氏距离
    return np.sqrt(np.sum((x1 - x2)**2))

def knn_predict(X_train, y_train, x_test, k=3):
    distances = []

    # 计算测试样本与所有训练样本的距离
    for i in range(len(X_train)):
        distance = euclidean_distance(x_test, X_train[i])
        distances.append((distance, y_train[i]))

    # 根据距离排序
    distances.sort(key=lambda x: x[0])

    # 取前k个最近邻
    neighbors = distances[:k]

    # 统计最近邻中类别出现的次数
    class_votes = {}
    for neighbor in neighbors:
        label = neighbor[1]
        if label in class_votes:
            class_votes[label] += 1
        else:
            class_votes[label] = 1

    # 返回投票最多的类别作为预测结果
    predicted_label = max(class_votes, key=class_votes.get)
    return predicted_label

def main():
    # 加载数据
    X, y = load_iris_data()

    # 将标签转换为数字形式
    label_encoder = LabelEncoder()
    y = label_encoder.fit_transform(y)

    # 划分训练集和测试集
    X_train = X[:100]
    y_train = y[:100]
    X_test = X[100:]
    y_test = y[100:]

    # 对测试集进行预测
    predictions = []
    for i in range(len(X_test)):
        prediction = knn_predict(X_train, y_train, X_test[i])
        predictions.append(prediction)

    # 打印混淆矩阵
    cm = confusion_matrix(y_test, predictions)
    print("Confusion Matrix:")
    print(cm)

if __name__ == "__main__":
    main()

